﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Citi.Helpers;
using EO.WebBrowser;
using EO.WebBrowser.WinForm;

namespace Citi.SecurityWebBrowser
{
    public abstract class EOWebBrowserUtil
    {      
        protected WebView WebBrowser;
        protected WebControl WebControl;
        protected Form FormParent { get; set; }
        protected string LocalPathToSave { get; set; }
        protected string LogPath { get; set; }
        protected string Parameters { get; set; }
        protected string StartUrl { get; set; }
        protected string SsoUrl { get; set; }
        protected string UserLogin { get; set; }
        protected DownloadItem DownloadItem { get; set; }
        protected string ReportName { get; set; }
        protected string PathToSave { get; set; }

        public EOWebBrowserUtil(WebControl webControl, string reportName, string startUrl, string ssoUrl, string userLogin, string pathToSave, string parameters, bool newWindowNoAction, Form form = null)
        {
            LogPath = string.Format(ConfigurationManager.AppSettings["LogPath"], FileHelper.MakeValidFileName(reportName));

            try
            {
                if (File.Exists(LogPath)) File.Delete(LogPath);
            }
            catch { }

            if (webControl == null)
            {
                webControl = new WebControl();
                webControl.WebView = new WebView();
            }

            WebControl = webControl;
            ReportName = reportName;

            WebBrowser = webControl.WebView;
            WebBrowser.BeforeDownload += webBrowser_BeforeDownload;
            WebBrowser.DownloadCompleted += webBrowser_DownloadCompleted;
            WebBrowser.DownloadUpdated += webBrowser_DownloadUpdated;

            if (newWindowNoAction)
                webControl.WebView.NewWindow += webBrowser_NewWindowNoAction;
            else
                webControl.WebView.NewWindow += webBrowser_NewWindowOpenTargetUrl;

            FormParent = form;
            FormParent.FormClosed += EOExtraction_FormClosed;
            FormParent.Load += EOExtraction_Load;
            PathToSave = pathToSave;
            Parameters = parameters;
            UserLogin = userLogin;
            StartUrl = startUrl;
            SsoUrl = ssoUrl;
            LocalPathToSave = Path.Combine(@"C:\temp", string.Concat(Guid.NewGuid(), Path.GetExtension(pathToSave)));

            if (File.Exists(LocalPathToSave)) File.Delete(LocalPathToSave);
        }

        void EOExtraction_FormClosed(object sender, FormClosedEventArgs e)
        {
            Environment.Exit(Environment.ExitCode);
        }

        private void EOExtraction_Load(object sender, EventArgs e)
        {
            WebControl.Height = FormParent.Height;
            WebControl.Width = FormParent.Width;
        }

        public abstract void StartExtractionLogged();

        public void StartExtraction(string additionalUrls = null)
        {
            try
            {
                Log(string.Format("Logging on Single Sign On as {0}", UserLogin));
                WebControl.LogSingleSignOn(UserLogin, SecurityHelper.LoginType.Sso, StartUrl, SsoUrl, additionalUrls);
                Log("Logged");

                StartExtractionLogged();

                while (DownloadItem == null)
                {
                    Application.DoEvents();
                    Thread.Sleep(100);
                }

                Log(string.Format("Saving file on '{0}'", PathToSave));
                File.Copy(LocalPathToSave, PathToSave, true);
                File.Delete(LocalPathToSave);
            }
            catch (Exception e)
            {
                Log(string.Format("#ERROR {0}. INNER EXCEPTION: {1}", e.Message, e.InnerException != null ? e.InnerException.Message : string.Empty));
            }
            finally
            {
                Log("Extractor will be closed");

                try
                {
                    Environment.Exit(Environment.ExitCode);
                }
                catch { }
            }
        }

        protected void webBrowser_NewWindowOpenTargetUrl(object sender, EO.WebBrowser.NewWindowEventArgs e)
        {
            e.Accepted = false;
            ((WebView)sender).LoadUrl(e.TargetUrl);
        }

        protected void webBrowser_NewWindowNoAction(object sender, EO.WebBrowser.NewWindowEventArgs e)
        {
            e.Accepted = false;
        }

        protected void Log(string message)
        {
            try
            {
                File.AppendAllLines(LogPath, new[] { message });
            }
            catch
            {

            }
        }

        int lastDownloadPercent = 0;

        protected void webBrowser_DownloadUpdated(object sender, DownloadEventArgs e)
        {
            if (lastDownloadPercent != 0 && lastDownloadPercent != e.Item.PercentageComplete && e.Item.PercentageComplete % 10 == 0)
                Log(string.Format("{0}% completed", e.Item.PercentageComplete));

            lastDownloadPercent = e.Item.PercentageComplete;

            UpdateFormTitle(string.Format("{0}% completed", e.Item.PercentageComplete));
        }

        protected void webBrowser_DownloadCompleted(object sender, DownloadEventArgs e)
        {
            Log("Download finished");
            UpdateFormTitle("Download finished");
            DownloadItem = e.Item;
        }

        protected void webBrowser_BeforeDownload(object sender, BeforeDownloadEventArgs e)
        {
            Log("Download has been started");
            UpdateFormTitle("Downloading");
            e.FilePath = LocalPathToSave;
            e.ShowDialog = false;
        }

        protected void UpdateFormTitle(string message)
        {
            if (FormParent == null) return;

            FormParent.Text = string.Format("{0} - {1}", WebBrowser.Title, message);
        }

        protected bool ClickOnElement(string javascriptClick, NavigationTaskEventHandler eventRemove, NavigationTaskEventHandler eventAdd)
        {
            if (!WebBrowser.AllElementExist(javascriptClick)) return false;

            if (eventRemove != null)
                WebBrowser.LoadComplete -= eventRemove;

            if (eventAdd != null)
                WebBrowser.LoadComplete += eventAdd;

            WebBrowser.EvaluateScript(string.Format("{0}.click();", javascriptClick));
            return true;
        }

        protected bool ClickOnElement(string elementToClickId, string locationElement, NavigationTaskEventHandler eventRemove, NavigationTaskEventHandler eventAdd)
        {
            var javascriptClick = string.Format("{0}document.getElementById('{1}')",
                string.IsNullOrWhiteSpace(locationElement)
                    ? string.Empty
                    : string.Concat(locationElement, ".")
                , elementToClickId);

            return ClickOnElement(javascriptClick, eventRemove, eventAdd);
        }

        protected void Wait(int miliseconds)
        {
            var sleepTime = 100;
            var i = 0;
            while (i < miliseconds / sleepTime)
            {
                i++;
                Application.DoEvents();
                Thread.Sleep(sleepTime);
            }
        }

        protected Dictionary<string, string> GetParametersDictionary()
        {
            var dictionary = new Dictionary<string, string>();

            var parametersSplited = Parameters.Split(new[] { @"]}" }, 200, StringSplitOptions.RemoveEmptyEntries);

            foreach (var parameter in parametersSplited)
            {
                var parameterSplited = parameter.Substring(2).Split(new[] { "][" }, 2, StringSplitOptions.RemoveEmptyEntries);

                dictionary.Add(parameterSplited[0], parameterSplited[1]);
            }

            return dictionary;
        }
    }
}
